#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <vector>
#include <cstdint>
#include <setjmp.h>
#include <wchar.h>
#include <hpdf.h>

#define FONT_PATH "/mnt/g/asus/Desktop/temp/Arial-Unicode-MS.ttf" // Arial Unicode MS字体文件路径
#define START_CHAR (000000)                  // Unicode编码 起始
#define END_CHAR (65536)                   // Unicode编码 结束
#define CHARACTERS_PER_LINE 10             // 每行 10 个字符
#define LINES_PER_PAGE 20                  // 每页20行
#define X_SPACEING 50                      // 每一行每个字符之间的间隔
#define Y_SPACEING 40                      // 每一行之间的行间距

// 3字节的 unicode 转 utf-8
std::vector<uint8_t> unicode_code_point_to_utf8(uint32_t code_point)
{
    std::vector<uint8_t> utf8_bytes;

    if (code_point <= 0x7F)
    {
        utf8_bytes.push_back(code_point);
    }
    else if (code_point <= 0x7FF)
    {
        utf8_bytes.push_back(0xC0 | ((code_point >> 6) & 0x1F));
        utf8_bytes.push_back(0x80 | (code_point & 0x3F));
    }
    else if (code_point <= 0xFFFF)
    {
        utf8_bytes.push_back(0xE0 | ((code_point >> 12) & 0x0F));
        utf8_bytes.push_back(0x80 | ((code_point >> 6) & 0x3F));
        utf8_bytes.push_back(0x80 | (code_point & 0x3F));
    }
    else if (code_point <= 0x10FFFF) //用不到
    {
        // 分解
        uint32_t lead_surrogate = (code_point >> 10) + 0xD800;
        uint32_t trail_surrogate = (code_point & 0x3FF) + 0xDC00;

        // 转换两个 UTF-8
        std::vector<uint8_t> lead_bytes = unicode_code_point_to_utf8(lead_surrogate);
        std::vector<uint8_t> trail_bytes = unicode_code_point_to_utf8(trail_surrogate);

        // 将两个 UTF-8 编码合并
        utf8_bytes.insert(utf8_bytes.end(), lead_bytes.begin(), lead_bytes.end());
        utf8_bytes.insert(utf8_bytes.end(), trail_bytes.begin(), trail_bytes.end());
    }
    else
    {
        std::cerr << "Invalid Unicode code point." << std::endl;
    }

    return utf8_bytes;
}

void error_handler(HPDF_STATUS error_no, HPDF_STATUS detail_no, void *user_data)
{
    printf("ERROR: error_no=%04X, detail_no=%u\n", (HPDF_UINT)error_no, (HPDF_UINT)detail_no);
    longjmp((__jmp_buf_tag *)user_data, 1);
}

int main(int argc, char **argv)
{
    HPDF_Doc pdf;
    HPDF_Font font;
    HPDF_Page page;
    jmp_buf env;
    unsigned char buf[8]; // 一个字符
    unsigned int i;

    pdf = HPDF_New(error_handler, env);
    if (!pdf)
    {
        printf("ERROR: cannot create pdf object.\n");
        return 1;
    }

    if (setjmp(env))
    {
        HPDF_Free(pdf);
        return 1;
    }

    // 使用 UTF-8 编码
    HPDF_UseUTFEncodings(pdf);
    HPDF_SetCurrentEncoder(pdf, "UTF-8");

    // 加载 Arial Unicode MS 字体
    const char *_font = HPDF_LoadTTFontFromFile(pdf, FONT_PATH, HPDF_TRUE);
    font = HPDF_GetFont(pdf, _font, "UTF-8");

    // 添加 页
    page = HPDF_AddPage(pdf);
    // 设置页的大小
    HPDF_Page_SetSize(page, HPDF_PAGE_SIZE_A4, HPDF_PAGE_PORTRAIT);

    HPDF_Page_BeginText(page);
    // 设置字体大小
    HPDF_Page_SetFontAndSize(page, font, 12);
    // 获取页高
    float height = HPDF_Page_GetHeight(page);
    float x = X_SPACEING * 11, y = height;
    HPDF_Page_MoveTextPos(page, x, y);
    int char_count = 0;
    int idx = 0;
    for (i = START_CHAR; i <= END_CHAR; i++)
    {
        if (char_count % CHARACTERS_PER_LINE == 0)
        {
            HPDF_Page_MoveTextPos(page, -X_SPACEING * 10, -40);
            // x = X_SPACEING;
            // y -= Y_SPACEING;
        }
        memset(buf, 0, sizeof(buf));
        // unicode 转 utf-8
        std::vector<uint8_t> tmp = unicode_code_point_to_utf8(i);
        for (int j = 0; j < tmp.size(); j++)
        {
            buf[j] = tmp[j];
        }
        HPDF_Page_ShowText(page, (const char *)buf);
        HPDF_Page_MoveTextPos(page, X_SPACEING, 0);

        x += X_SPACEING;
        char_count++;
        if (char_count % 200 == 0)
        {
            HPDF_Page_EndText(page);
            char_count = 0;
            x = X_SPACEING * 11;
            y = height;
            page = HPDF_AddPage(pdf);
            HPDF_Page_BeginText(page);
            HPDF_Page_SetFontAndSize(page, font, 12);
            HPDF_Page_MoveTextPos(page, x, y);

            // 超过 200 进行分页
        }
    }

    HPDF_Page_EndText(page);
    // 保存结果
    HPDF_SaveToFile(pdf, "Unicode-MS.pdf");
    HPDF_Free(pdf);

    return 0;
}